﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenCvSharp;

namespace LicenseAutoDetection
{
    public class GROUPHEADER
    {
        public int HeaderSeq = 1;
        public int AllpixelCnt;
        public int minX, maxX;
        public int minY, maxY;
        public GROUPINFO includeinfo;
        public GROUPHEADER prev;
        public GROUPHEADER next;
    }

    public class GROUPINFO
    {
        public GROUPHEADER header;
        public int GroupName;
        public int pixelCnt;
        public int minX, maxX;
        public int minY, maxY;
        public GROUPINFO prev;
        public GROUPINFO next;
    }

    class GroupList
    {
        public GROUPHEADER Biggest
        {
            get { return BiggestHeader; }
            set { BiggestHeader = value; }
        }

        GROUPHEADER BiggestHeader = null;

        public void HeaderInitalize(GROUPHEADER header, GROUPINFO info)
        {
            header.AllpixelCnt = 0;
            header.includeinfo = info;
            header.prev = null;
            header.next = null;
        }

        public void Readjust(GROUPINFO _group, int _y, int _x)
        {
            if (_group.minY > _y) _group.minY = _y;
            if (_group.maxY < _y) _group.maxY = _y;

            if (_group.minX > _x) _group.minX = _x;
            if (_group.maxX < _x) _group.maxX = _x;

            if (_group.header.minY > _group.minY) _group.header.minY = _group.minY;
            if (_group.header.maxY < _group.maxY) _group.header.maxY = _group.maxY;

            if (_group.header.minX > _group.minX) _group.header.minX = _group.minX;
            if (_group.header.maxX < _group.maxX) _group.header.maxX = _group.maxX;
        }

        public GROUPINFO GroupFind(GROUPHEADER header, int groupNum)
        {
            GROUPHEADER temp = header;
            GROUPINFO grouptemp;

            while (temp != null)
            {
                grouptemp = temp.includeinfo;
                while (grouptemp != null)
                {
                    if (grouptemp.GroupName == groupNum)
                        return grouptemp;

                    grouptemp = grouptemp.next;
                }
                temp = temp.next;
            }
            
            return null;
        }
        
        //public bool IsGroup(GROUPHEADER header, int group, int group2)
        //{
        //    GROUPINFO temp = GroupFind(header, group).header.includeinfo;

        //    while (temp != null)
        //    {
        //        if (temp.GroupName == group2) return true;
        //        temp = temp.next;
        //    }
        //    return false;
        //}

        public bool IsGroup(GROUPINFO group1, GROUPINFO group2)
        {
            return (group1.header == group2.header) ? true : false;
        }

        public void AppendGroup(GROUPINFO group, GROUPINFO append)
        {
            GROUPINFO dsttemp = group;
            GROUPINFO srctemp = append;
            GROUPHEADER DelGroupHeader = null;

            if (dsttemp == null || srctemp == null) MessageBox.Show("Not found a group !");

            if (dsttemp.header.HeaderSeq > srctemp.header.HeaderSeq)
            {
                dsttemp = append;
                srctemp = group;
            }

            DelGroupHeader = srctemp.header;

            dsttemp.header.AllpixelCnt += srctemp.header.AllpixelCnt;

            while (dsttemp.next != null)
                dsttemp = dsttemp.next;

            if (srctemp.header.includeinfo != srctemp || srctemp.next != null)
                srctemp = srctemp.header.includeinfo;
            else
                srctemp.header.includeinfo = null;
            
            dsttemp.next = srctemp;
            srctemp.prev = dsttemp;
            srctemp.header = dsttemp.header;

            while (srctemp != null)
            {
                srctemp.header = dsttemp.header;
                srctemp = srctemp.next;
            }

            DelGroupHeader.prev.next = DelGroupHeader.next;
            if (DelGroupHeader.next != null)
                DelGroupHeader.next.prev = DelGroupHeader.prev;
        }
        
        public GROUPINFO AddGroup(GROUPHEADER header, int groupNum)
        {
            GROUPHEADER temp = header;
            GROUPINFO NewGroup = new GROUPINFO();

            NewGroup.GroupName = groupNum;
            NewGroup.header = null;
            NewGroup.prev = null;
            NewGroup.next = null;

            if (temp.includeinfo == null)
            {
                temp.includeinfo = NewGroup;
                NewGroup.header = header;
            }
            else
            {
                while (temp.next != null)
                    temp = temp.next;

                temp.next = new GROUPHEADER();
                temp.next.HeaderSeq = temp.HeaderSeq + 1;
                HeaderInitalize(temp.next, NewGroup);
                NewGroup.header = temp.next;
                temp.next.prev = temp;
            }

            if (BiggestHeader == null)
                BiggestHeader = temp;

            return NewGroup;
        }
    }
}
